package org.zjvis.datascience.service.csv;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.zjvis.datascience.common.constant.FileConstant;
import org.zjvis.datascience.common.util.RedisUtil;

import java.io.File;
import java.util.Date;
import java.util.Iterator;

/**
 * @description CSV 文件上传缓存数据
 * @date 2021-12-29
 */
@Component
public class CsvFileCleanTask {

    @Value("${upload.folderpath}")
    private String sliceFolderPath;
    @Value("${upload.expireTime}")
    private long expireTime;

    @Autowired
    RedisUtil redisUtil;

    private final static Logger logger = LoggerFactory.getLogger(CsvFileCleanTask.class);

    // 每天0点
    @Scheduled(cron = "0 0 0 * * ?")
    public void clean() {
        logger.info("清理csv导入缓存数据");
        long cnt = 0;
        File dir = new File(sliceFolderPath);
        if (dir.exists()) {
            redisUtil.hdelAll(FileConstant.FILE_IS_ING);
            // expireTime之前的文件
            Date pointDate = new Date(System.currentTimeMillis() - 1000 * expireTime);
            // 文件过滤条件
            IOFileFilter timeFileFilter = new AgeFileFilter(pointDate, true);
            IOFileFilter fileFiles = new AndFileFilter(DirectoryFileFilter.DIRECTORY, timeFileFilter);
            File directory = new File(sliceFolderPath);
            // dirFilter 是目录的过滤器，而fileFile是文件的过滤器，在iterateFilesAndDirs会和目录过滤器求和，该结果最后会做或运算
            // 因此如果随意使用FileFilter对于文件会返回true，或运算都会筛选出来，因此希望其一直是false，因此引入DirectoryFileFilter.INSTANCE，保证文件一定不会筛选出来
            // 对于目录的过滤器采用事先制定的时间过滤以及Directory过滤（第二个过滤其实不用，方法内会拿这个和自定义的求和，即FileFilterUtils.and(dirFilter,DirectoryFileFilter.INSTANCE)）
            // 因此最终过滤的就说满足所有条件的目录文件，父目录子目录均有
            Iterator<File> itFile = FileUtils.iterateFilesAndDirs(directory, DirectoryFileFilter.INSTANCE, fileFiles);
            // 删除符合条件的文件
            while (itFile.hasNext()) {
                File file = itFile.next();
                // 不要父目录也不要子目录
                if (!file.getParent().equals(directory.getPath())) continue;
                String name = file.getName(); // MD5值
                if (FileUtils.deleteQuietly(file)) {
                    redisUtil.allDel(FileConstant.FILE_UPLOAD_PREVIEW_DATA + "_" + name);
                    redisUtil.allDel(FileConstant.FILE_UPLOAD_FILENAME + "_" + name);
                    redisUtil.allDel(FileConstant.FILE_HEADER + "_" + name);
                    redisUtil.allDel("csvResult_" + name);
                    redisUtil.hdelAll(FileConstant.FILE_CHECK_PROGRESS, name);
                    redisUtil.hdelAll(FileConstant.FILE_UPLOAD_COMPLETE, name);
                    redisUtil.allDel(FileConstant.FILE_CHUNK_SEG_INFO + "_" + name);
                    cnt++;
                }
            }
        }
        logger.info("清理完毕，共清除 {} 个文件", cnt);
    }
}
